/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/*
 * TablePanel.java
 *
 * Created on 2010-9-29, 21:22:34
 */

package Table;

import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Vector;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JOptionPane;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.table.TableColumn;
import javax.swing.table.TableColumnModel;

/**
 *
 * @author Administrator
 */
public class TablePanel extends javax.swing.JPanel {

    //TableValues tv;
    private getAllInfo data;
    private TableInfoCenter TIC;
    private myTableModel tablemodel;
    private String[] columnName;

    private int originalRowNum;

    private List<Object[]> addedItem;
    private List<Object[]> updatedItem;
    private List<String> deletedItemID;
    private Map<String, Integer> record;
    private static final int sUPDATE = 1;
    private static final int sDELETE = 2;
    private static final int sADD = 3;
    private static final int sORIGINAL = 4;

    private void setup() {
        
        deletedItemID = new Vector();
        addedItem = new Vector();
        updatedItem = new Vector();
        record = new HashMap();

        try {
            this.TIC = data.getAllInfo();
        } catch (Exception ex) {
            Logger.getLogger(TablePanel.class.getName()).log(Level.SEVERE, null, ex);
        }

        originalRowNum = TIC.InfoSet.size();

        String[] temp = new String[TIC.ColumnInfo.length];
        for(int i = 0; i < TIC.ColumnInfo.length; ++i) {
            temp[i] = TIC.ColumnInfo[i].getName();
        }
        columnName = temp;
        Object[][] obj = new Object[TIC.InfoSet.size()][TIC.ColumnInfo.length];
        for(int i = 0; i < TIC.InfoSet.size(); ++i) {
            obj[i] = TIC.InfoSet.get(i);
            record.put(obj[i][0].toString(), TablePanel.sORIGINAL);
        }
        tablemodel = new myTableModel(obj, columnName, TIC.ColumnInfo);
    }

    private void setupAfterInit() {
        TableColumnModel tcm = jTable1.getColumnModel();
        for(int i = 0; i < tcm.getColumnCount(); ++i) {
            TableColumn tc = tcm.getColumn(i);
            tc.setPreferredWidth(TIC.ColumnInfo[i].getColumnWidth());
        }
    }

    /** Creates new form TablePanel */
    public TablePanel(getAllInfo data) {
        this.data = data;
        setup();
        initComponents();
        setupAfterInit();
        setListener();
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jScrollPane1 = new javax.swing.JScrollPane();
        jTable1 = new javax.swing.JTable();
        jTextField1 = new javax.swing.JTextField();
        NewButton = new javax.swing.JButton();
        SaveButton = new javax.swing.JButton();
        DelButton = new javax.swing.JButton();

        jTable1.setModel(tablemodel);
        jTable1.setAutoResizeMode(javax.swing.JTable.AUTO_RESIZE_OFF);
        jScrollPane1.setViewportView(jTable1);
        jTable1 .getTableHeader().setReorderingAllowed(false);

        jTextField1.setText("jTextField1");

        NewButton.setText("New");
        NewButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                NewButtonActionPerformed(evt);
            }
        });

        SaveButton.setText("Save");
        SaveButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                SaveButtonActionPerformed(evt);
            }
        });

        DelButton.setText("Del");
        DelButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                DelButtonActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
        this.setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGap(144, 144, 144)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup()
                        .addComponent(NewButton)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 177, Short.MAX_VALUE)
                        .addComponent(SaveButton)
                        .addGap(162, 162, 162)
                        .addComponent(DelButton))
                    .addComponent(jTextField1, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 498, Short.MAX_VALUE)
                    .addComponent(jScrollPane1, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.PREFERRED_SIZE, 498, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addContainerGap(127, Short.MAX_VALUE))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jTextField1, javax.swing.GroupLayout.PREFERRED_SIZE, 34, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 361, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(18, 18, 18)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(NewButton)
                    .addComponent(DelButton)
                    .addComponent(SaveButton))
                .addContainerGap(27, Short.MAX_VALUE))
        );
    }// </editor-fold>//GEN-END:initComponents

    private void NewButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_NewButtonActionPerformed
        // TODO add your handling code here:
        this.tablemodel.addRow(new Object[]{});
        int row = tablemodel.getDataVector().size() - 1;
        jTable1.setRowSelectionInterval(row, row);
        jTable1.scrollRectToVisible(jTable1.getCellRect(row, 0, true));
    }//GEN-LAST:event_NewButtonActionPerformed

    private boolean validated(int i) {
        List<Object> rowdata = (List<Object>) tablemodel.getDataVector().get(i);
        String ID = (String) rowdata.get(0);
        for(int m = 0; m < TIC.ColumnInfo.length; ++m) {
            if(TIC.ColumnInfo[m].isNotnull()) {
                if(rowdata.get(m) == null || rowdata.get(m).equals("")) {
                    return false;
                }
            }
        }
        return true;
    }

    private void SaveButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_SaveButtonActionPerformed
        // TODO add your handling code here:
        List<List<Object>> datalist = tablemodel.getDataVector();
        boolean canSave = true;

//        Set<Map.Entry<String, Integer>> setofrecord = record.entrySet();
//        Iterator i = setofrecord.iterator();
//        while(i.hasNext()) {
//
//        }

        for(int i = 0; i < datalist.size(); ++i) {
            if(!validated(i)) {
                popWarning("Don't leave invalid entry in table! Delete or fill.");
                jTable1.setRowSelectionInterval(i, i);
                jTable1.scrollRectToVisible(jTable1.getCellRect(i, 0, true));
                canSave = false;
                break;
            }
            String ID = (String) datalist.get(i).get(0);
//            if(record.get(ID) == null) {
//                popWarning("Don't leave invalid entry in table! Delete or fill.");
//                canSave = false;
//                break;
//            }
            switch(record.get(ID)) {
                case TablePanel.sADD: addedItem.add(datalist.get(i).toArray()); break;
                case TablePanel.sDELETE: deletedItemID.add(ID);break;
                case TablePanel.sUPDATE: updatedItem.add(datalist.get(i).toArray());break;
                case TablePanel.sORIGINAL:break;
//                default:popWarning("Don't leave invalid entry in table! Delete or fill.");canSave = false;break;
            }
//            if(!canSave) {
//                break;
//            }
        }
        if(!canSave) {
            this.addedItem.clear();
            this.updatedItem.clear();
            this.deletedItemID.clear();
            return;
        }


        //保存
        data.saveToDatabase(addedItem, updatedItem, deletedItemID);

//        Set<Map.Entry<String, Integer>> temp = record.entrySet();
//        Iterator tttt = temp.iterator();
//        while(tttt.hasNext()) {
//            System.out.println(tttt.next());
//        }
////        Map.Entry<String, Integer>[] temp1 = temp.toArray(Map.Entry<String, Integer>[] a);
////        Map.Entry<String, Integer> temp2 = (Map.Entry<String, Integer>) temp1;
////        Set<String> ttt = record.keySet();
////        Object[] tt = ttt.toArray();
////        for(int i = 0; i < record.size(); ++i) {
////            System.out.print(tt[i]+" ");
////        }
//        System.out.println();
//
//        System.out.println("add:");
//        for(int i = 0; i < addedItem.size(); ++i) {
//            for(int j = 0; j < addedItem.get(i).length; ++j) {
//                System.out.print(addedItem.get(i)[j]+" ");
//            }
//            System.out.println();
//        }
//        System.out.println("update:");
//        for(int i = 0; i < updatedItem.size(); ++i) {
//            for(int j = 0; j < updatedItem.get(i).length; ++j) {
//                System.out.print(updatedItem.get(i)[j]+" ");
//            }
//            System.out.println();
//        }
//        System.out.println("delete:");
//        for(int i = 0; i < deletedItemID.size(); ++i) {
//            System.out.println(deletedItemID.get(i));
//        }
       

        try {
            this.TIC = data.getAllInfo();
        } catch (Exception ex) {
            Logger.getLogger(TablePanel.class.getName()).log(Level.SEVERE, null, ex);
        }

        originalRowNum = TIC.InfoSet.size();

        Object[][] obj = new Object[TIC.InfoSet.size()][TIC.ColumnInfo.length];
        for(int i = 0; i < TIC.InfoSet.size(); ++i) {
            obj[i] = TIC.InfoSet.get(i);
        }
        while(tablemodel.getDataVector().size() != 0) {
            tablemodel.removeRow(0);
        }
        for(int i = 0; i < obj.length; ++i) {
            tablemodel.addRow(obj[i]);
        }
        this.addedItem.clear();
        this.updatedItem.clear();
        this.deletedItemID.clear();
        this.record.clear();
        for (int i = 0; i < TIC.InfoSet.size(); ++i) {
            record.put(obj[i][0].toString(), TablePanel.sORIGINAL);
        }
    }//GEN-LAST:event_SaveButtonActionPerformed

    private void DelButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_DelButtonActionPerformed
        // TODO add your handling code here:
        int[] selected = jTable1.getSelectedRows();
        int i, effectiveDeletedItemThisTime = 0;
        if(selected.length != 0) {
            for(i = 0; i < selected.length; ++i) {
                List<List<Object>> datalist = tablemodel.getDataVector();
                String ID = (String) datalist.get(selected[i]).get(0);
                if(selected[i] < originalRowNum) {
                    record.put(ID, TablePanel.sDELETE);
                    deletedItemID.add(ID);
                    effectiveDeletedItemThisTime += 1;
                    System.out.println(datalist.get(selected[i]).get(0).toString());
                } else {
                    if(record.containsKey(ID)) {
                        record.remove(ID);
                    }
                }
            }
            originalRowNum -= effectiveDeletedItemThisTime;
            for(i = 0; i < selected.length; ++i) {
                tablemodel.removeRow(selected[i] - i);
            }
            int row = selected[selected.length - 1] - i + 1;
            if(row == tablemodel.getRowCount()) {
                row -= 1;
            }
            if(row != -1) {
                jTable1.setRowSelectionInterval(row, row);
                jTable1.scrollRectToVisible(jTable1.getCellRect(row, 0, true));
            }
        }
    }//GEN-LAST:event_DelButtonActionPerformed


    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton DelButton;
    private javax.swing.JButton NewButton;
    private javax.swing.JButton SaveButton;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JTable jTable1;
    private javax.swing.JTextField jTextField1;
    // End of variables declaration//GEN-END:variables


    //设置表头，在initComponents中调用

    private void popWarning(String str) {
        JOptionPane.showMessageDialog(null, str);
    }

    private void setListener() {
        //throw new UnsupportedOperationException("Not yet implemented");
//        TableColumnModel tcm = jTable1.getColumnModel();
//        Integer[] temp = new Integer[30];
//        int num = 0;
//        for(int i = 0; i < TIC.ColumnInfo.size(); ++i) {
//            if(TIC.ColumnInfo.get(i).isNeedComboBox())
//                temp.add(i);
//        }
//        List<TableColumn> tc = new ArrayList();
//        for(int i = 0; i < temp.size(); ++i) {
//            tc.add(tcm.getColumn(temp.get(i)));
//        }
//        for(int i = 0; i < tc.size(); ++i) {
//            tc.get(i).setCellRenderer(new CellRender());
//            tc.get(i).setCellEditor(new DefaultCellEditor(new CellJComboBox()));
//        }
        tablemodel.addTableModelListener(new TableModelListener(){

            public void tableChanged(TableModelEvent e) {
                //throw new UnsupportedOperationException("Not supported yet.");

                int type = e.getType();
                if(type == TableModelEvent.UPDATE) {
                    int row = e.getFirstRow();
                    int column = e.getColumn();
                    List<List<Object>> datalist = tablemodel.getDataVector();
                    String ID = (String) datalist.get(row).get(0);
                    if(row < originalRowNum) {
                        record.put(ID, TablePanel.sUPDATE);
                    } else {
//                        if (ID == null) {
//                            popWarning("Set ID first, please.");
////                            tablemodel.setValueAt(null, row, column);
//                            return ;
//                        }
                        if (column == 0) {
                            if (ID != null && !ID.equals("")) {
                                if (record.containsKey(ID)) {
                                    popWarning("Choose a unique ID please");
                                    tablemodel.setValueAt(null, row, column);
                                } else {
                                    record.put(ID, TablePanel.sADD);
                                }
                            }
                        }
                    }
                }
            }

        });
    }


}
